﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.Custom;
using DWF.Studio.ISerivces;
using DWF.Studio.Models;
using DWF.Studio.Project;
using DWF.Studio.Share.Serialization;
using DWF.Studio.Share.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DWF.Studio.Services
{
    internal class ProjectRecordsService : IProjectRecordsService
    {
        private const int _maxRecordCount = 20;

        public IEnumerable<ProjectRecord> GetRecentRecords()
        {
            var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var appdatapath = System.IO.Path.Combine(localAppData, StaticResource.ProcessGo, StaticResource.Studio);
            var recordfile = System.IO.Path.Combine(appdatapath, StaticResource.ProjectRecord);

            if (!FileHelper.CheckFolderExisting(appdatapath))
            {
                FileHelper.CreateFolder(appdatapath);
            }

            List<ProjectRecord> projectRecords = null;
            if (FileHelper.CheckFileExisting(recordfile))//检查配置文件是否存在，如果存在这加载，否者新建。
            {
                projectRecords = YamlHelper.Load<List<ProjectRecord>>(recordfile, true);
            }
            else
            {
                projectRecords = new List<ProjectRecord>();
                YamlHelper.Save(projectRecords, recordfile, true);
            }

            return projectRecords.OrderByDescending(item => item.ModifyOn);
        }

        public async Task<IEnumerable<ProjectRecord>> GetRecentRecordsAsync()
        {
            IEnumerable<ProjectRecord> projectRecords = null;
            await Task.Run(() =>
            {
                projectRecords = GetRecentRecords();
            });

            return projectRecords;
        }

        public void SetRecord(ProjectRecord record)
        {
            var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var appdatapath = System.IO.Path.Combine(localAppData, StaticResource.ProcessGo, StaticResource.Studio);
            var recordfile = System.IO.Path.Combine(appdatapath, StaticResource.ProjectRecord);

            if (!FileHelper.CheckFolderExisting(appdatapath))
            {
                FileHelper.CreateFolder(appdatapath);
            }

            List<ProjectRecord> projectRecords = null;
            if (FileHelper.CheckFileExisting(recordfile))//检查配置文件是否存在，如果存在这加载，否者新建。
            {
                projectRecords = YamlHelper.Load<List<ProjectRecord>>(recordfile, true);
            }
            else
            {
                projectRecords = new List<ProjectRecord>();
            }

            var existRecord = projectRecords.FirstOrDefault(item => item.ProjectPath == record.ProjectPath);
            if (existRecord != null)
            {
                existRecord.ProjectName = record.ProjectName;
                existRecord.ProjectPath = record.ProjectPath;
                existRecord.ModifyOn = DateTime.Now;
            }
            else
            {
                if (projectRecords.Count > _maxRecordCount)
                {
                    var mixRecord = projectRecords.FirstOrDefault(item => item.ModifyOn == projectRecords.Min(i => i.ModifyOn)); //找到最早的记录
                    if (mixRecord != null)
                    {
                        projectRecords.Remove(mixRecord);
                    }
                }

                projectRecords.Add(record);
            }

            YamlHelper.Save(projectRecords, recordfile, true);
        }

        public void DelectRecord(string projectPath)
        {
            var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var appdatapath = System.IO.Path.Combine(localAppData, StaticResource.ProcessGo, StaticResource.Studio);
            var recordfile = System.IO.Path.Combine(appdatapath, StaticResource.ProjectRecord);

            if (!FileHelper.CheckFolderExisting(appdatapath))
            {
                FileHelper.CreateFolder(appdatapath);
            }

            List<ProjectRecord> projectRecords = null;
            if (FileHelper.CheckFileExisting(recordfile))//检查配置文件是否存在，如果存在这加载，否者新建。
            {
                projectRecords = YamlHelper.Load<List<ProjectRecord>>(recordfile, true);
            }
            else
            {
                projectRecords = new List<ProjectRecord>();
            }

            var existRecord = projectRecords.FirstOrDefault(item => item.ProjectPath == projectPath);
            if (existRecord != null)
            {
                projectRecords.Remove(existRecord);
                YamlHelper.Save(projectRecords, recordfile, true);
            }
        }

        public void ClearRecords()
        {
            var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var appdatapath = System.IO.Path.Combine(localAppData, StaticResource.ProcessGo, StaticResource.Studio);
            var recordfile = System.IO.Path.Combine(appdatapath, StaticResource.ProjectRecord);

            if (!FileHelper.CheckFolderExisting(appdatapath))
            {
                FileHelper.CreateFolder(appdatapath);
            }

            List<ProjectRecord> projectRecords = null;
            if (FileHelper.CheckFileExisting(recordfile))//检查配置文件是否存在，如果存在这加载，否者新建。
            {
                projectRecords = YamlHelper.Load<List<ProjectRecord>>(recordfile, true);
            }
            else
            {
                projectRecords = new List<ProjectRecord>();
            }

            projectRecords.Clear();
            YamlHelper.Save(projectRecords, recordfile, true);
        }

        public IEnumerable<ProjectRecord> GetDemoRecords()
        {
            var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, StaticResource.HelpDocumnet, StaticResource.Examples);

            List<ProjectRecord> demoRecords = new List<ProjectRecord>();
            if (FileHelper.CheckFolderExisting(path))
            {
                string[] projects = System.IO.Directory.GetFiles(path, ".project", SearchOption.AllDirectories);
                string[] pgos = System.IO.Directory.GetFiles(path, ".pgo", SearchOption.AllDirectories);
                if (projects != null)
                {
                    foreach (var project in projects)
                    {
                        ProjectDetail detail = YamlHelper.Load<ProjectDetail>(project, true);
                        if (detail != null)
                        {
                            demoRecords.Add(new ProjectRecord() { ProjectId = detail.id, ProjectName = detail.name, ProjectPath = System.IO.Path.GetDirectoryName(project), ProjectDescription = detail.description, ModifyOn = DateTime.Now });
                        }
                    }
                }
                if (pgos != null)
                {
                    foreach (var pgo in pgos)
                    {
                        ProjectDetail detail = YamlHelper.Load<ProjectDetail>(pgo, true);
                        if (detail != null)
                        {
                            demoRecords.Add(new ProjectRecord() { ProjectId = detail.id, ProjectName = detail.name, ProjectPath = System.IO.Path.GetDirectoryName(pgo), ProjectDescription = detail.description, ModifyOn = DateTime.Now });
                        }
                    }
                }
            }

            return demoRecords;
        }

        public async Task<IEnumerable<ProjectRecord>> GetDemoRecordsAsync()
        {
            IEnumerable<ProjectRecord> demoRecords = null;
            await Task.Run(() =>
            {
                demoRecords = GetDemoRecords();
            });

            return demoRecords;
        }
    }
}
